<template>
  <div class="iot-dialog">
    <el-dialog class="custom-dialog" :visible.sync="dialogFormVisible" :append-to-body="true" :close-on-click-modal="false" @close="close"
               @open="open">
      <el-dialog
        top="4vh"
        destroy-on-close
        :visible.sync="innerVisible"
        append-to-body>
        <div slot="title">
          <div style="color:#fff">地图定位</div>
        </div>
        <div id="mapDiv" style="height:680px;width:920px"/>
      </el-dialog>
      <div style="position:absolute;top:120px;right:100px;z-index:999999;width:120px;height:160px;">
        <el-upload
          :disabled="type=='detail'"
          class="driver-uploader"
          action="iotAction"
          :show-file-list="false"
          :http-request="uploadSectionFile">
          <img v-if="imageUrl" :src="imageUrl" class="avatar">
          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
        <div style="text-align:center;line-height:40px;">添加照片</div>
      </div>
      <div slot="title">
        <div style="color:#fff">{{title}}</div>
      </div>
      <el-form :model="form" :rules="iotRules" ref="iotForm">
        <el-row :gutter="10">
          <el-col :span="8">
            <el-form-item label="设备名称" :label-width="formLabelWidth" prop="name">
              <el-input v-model.trim="form.name" autocomplete="off" placeholder="请填写设备名称"
                        :disabled="type=='detail'"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="设备类型" :label-width="formLabelWidth" prop="type">
              <el-select v-model="form.type" placeholder="请选择设备类型" :disabled="type=='detail'">
                <el-option v-for="item in iotTypeOptions" :key="item.dictCode" :label="item.dictLabel"
                           :value="item.dictValue"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="8">
            <el-form-item label="设备型号" :label-width="formLabelWidth" prop="model">
              <el-input v-model.trim="form.model" autocomplete="off" placeholder="请填写设备型号"
                        :disabled="type=='detail'"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="8">
            <el-form-item label="设备编号" :label-width="formLabelWidth" prop="code">
              <el-input v-model.trim="form.code" autocomplete="off" placeholder="请填写设备编号"
                        :disabled="type=='detail'"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="8">
            <el-form-item label="企业名称" :label-width="formLabelWidth" prop="enterpriseName">
              <el-input v-model.trim="form.enterpriseName" autocomplete="off" placeholder="请填写企业名称"
                        :disabled="type=='detail'"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="9">
            <el-form-item label="设备位置" :label-width="formLabelWidth" prop="locationEw">
              <div style="display: flex">
                <el-input style="width:200px" v-model="form.locationEw" autocomplete="off" placeholder="请填写经度"
                          :disabled="type=='detail'"></el-input>
                <label>&nbsp;&nbsp;EW&nbsp;&nbsp;</label>
              </div>
            </el-form-item>
          </el-col>
          <el-col :span="9">
            <el-form-item prop="locationNs">
              <div style="display: flex">
                <el-input style="width:200px" v-model="form.locationNs" autocomplete="off" placeholder="请填写纬度"
                          :disabled="type=='detail'"></el-input>
                <label>&nbsp;&nbsp;NS</label>
                <el-button type="primary" style="margin-left:20px" @click="handleClickMap" :disabled="type=='detail'">
                  地图定位
                </el-button>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="10">
          <el-col :span="8">
            <el-form-item label="接入时间" :label-width="formLabelWidth" prop="accessTime">
              <el-date-picker
                :disabled="type=='detail'"
                style="width:200px"
                v-model="form.accessTime"
                type="datetime"
                value-format="yyyy-MM-dd HH:mm:ss"
                placeholder="选择接入时间">
              </el-date-picker>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="备注" :label-width="formLabelWidth" prop="remarks">
          <el-input v-model.trim="form.remarks"
                    :disabled="type=='detail'"
                    type="textarea"
                    :rows="2"
                    placeholder="请输入备注信息"/>
        </el-form-item>
      </el-form>
      <div slot="footer" style="margin-top:-34px">
        <el-button v-if="type=='detail'" @click="handleClickSubmit">取&nbsp;&nbsp;消</el-button>
        <el-button v-if="type!='detail'" type="primary" @click="handleClickSubmit" :loading="addStatus">完&nbsp;&nbsp;成
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
    import {
        addFacility,
        updateFacility,
        getLandProperties
    } from '@/api/material'
    import {
        upload
    } from '@/api/upload'
    import "ol/ol.css"
    import Fill from "ol/style/Fill"
    import Map from "ol/Map"
    import View from "ol/View"
    import {Vector, Tile as TileLayer} from "ol/layer"
    import {OSM, Vector as VectorSource} from "ol/source"
    import {GeoJSON} from "ol/format"
    import {Style, Stroke, Circle as CircleStyle} from "ol/style"
    import {fromLonLat, transformExtent} from "ol/proj"
    import {
        Select,
        DoubleClickZoom,
        DragPan,
        MouseWheelZoom,
        Draw, Modify, Snap
    } from "ol/interaction"
    import ImageWMS from "ol/source/ImageWMS"
    import Image from "ol/layer/Image"

    export default {
        data() {
            const validateLocationEw = (rule, value, callback) => {
                if (value == null || value == '' || value == undefined) {
                    callback(new Error('经度不能为空'))
                } else {
                    const reg = /^([+]\d+[.]\d+|[-]\d+[.]\d+|\d+[.]\d+|[+]\d+|[-]\d+|\d+)$/gi　　　　　　//数字开始，数字结束
                    const dataArr = (this.form.locationEw + "").match(reg)
                    if (dataArr == null || dataArr.length == 0) {
                        callback(new Error('经度格式错误'))
                    }
                    callback()
                }
            }
            const validateLocationNs = (rule, value, callback) => {
                if (value == null || value == '' || value == undefined) {
                    callback(new Error('纬度不能为空'))
                } else {
                    const reg = /^([+]\d+[.]\d+|[-]\d+[.]\d+|\d+[.]\d+|[+]\d+|[-]\d+|\d+)$/gi　　　　　　//数字开始，数字结束
                    const dataArr = (this.form.locationNs + "").match(reg)
                    if (dataArr == null || dataArr.length == 0) {
                        callback(new Error('纬度格式错误'))
                    }
                    callback()
                }
            }
            return {
                addStatus: false,
                map: null,
                image: null,
                raster: null,
                draw: null,
                snap: null,
                source: null,
                genJson: null,
                pointArray: [],
                type: "",
                title: "",
                imageUrl: "",
                dialogFormVisible: false,
                innerVisible: false,
                iotTypeOptions: [],
                form: {
                    name: '',
                    code: '',
                    photoUrl: '',
                    type: '',
                    model: '',
                    resource: '',
                    remarks: '',
                    accessTime: null,
                    enterpriseName: '',
                    locationEw: null,
                    locationNs: null
                },
                iotRules: {
                    name: [
                        {required: true, message: '请输入设备名称', trigger: 'blur'},
                        {min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: 'blur'}
                    ],
                    code: [
                        {required: true, message: '请输入设备编号', trigger: 'blur'},
                        {min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: 'blur'}
                    ],
                    type: [
                        {required: true, message: '请选择设备', trigger: 'change'}
                    ],
                    locationNs: [
                        {required: true, message: '经度不能为空', trigger: 'blur'},
                        {validator: validateLocationNs, trigger: 'blur'}
                    ],
                    locationEw: [
                        {required: true, message: '纬度不能为空', trigger: 'blur'},
                        {validator: validateLocationEw, trigger: 'blur'}
                    ],
                    accessTime: [
                        {required: true, message: '请选择接入时间', trigger: 'change'}
                    ]
                },
                formLabelWidth: '80px'
            };
        },
        methods: {
            show(status, type, typeOptions, object) {
                this.type = type
                this.dialogFormVisible = status
                this.iotTypeOptions = typeOptions
                switch (this.type) {
                    case 'add':
                        this.requestBaseMap()
                        this.$nextTick(() => {
                            this.$refs.iotForm.resetFields()
                            this.$refs.iotForm.clearValidate()
                        })
                        this.title = '添加设备'
                        break;
                    case 'update':
                        this.requestBaseMap()
                        this.title = '修改设备'
                        this.$nextTick(()=>{
                            this.setFormWithObject(object.row)
                        })
                        break;
                    case 'detail':
                        this.title = '设备详情'
                        this.$nextTick(()=>{
                            this.setFormWithObject(object.row)
                        })
                        break;
                }
            },
            setFormWithObject(obj) {
                this.form.accessTime = obj.accessTime
                this.form.enterpriseName = obj.enterpriseName
                this.form.locationEw = obj.locationEw*1
                this.form.locationNs = obj.locationNs*1
                this.form.name = obj.name
                this.form.model = obj.model
                this.form.type = obj.type
                this.form.code = obj.code
                this.form.remarks = obj.remarks
                if(obj.photoUrl){
                    this.imageUrl = obj.photoUrl
                }
                if(this.type=='update'){
                    this.form.photoUrl = obj.photoUrl
                    this.form.id = obj.id
                }
            },
            handleClickSubmit() {
                switch (this.type) {
                    case 'add':
                        this.addAction()
                        break;
                    case 'update':
                        this.updateAction()
                        break;
                    case 'detail':
                        this.dialogFormVisible = false
                        break;
                }
            },
            updateAction(){
                this.$refs.iotForm.validate((valid) => {
                    if (valid) {
                        this.addStatus = true
                        const params = this.$cloneDeep(this.form)
                        console.log("要修改的数据", params)
                        const loading = this.$load(this)
                        updateFacility(params).then(response => {
                            console.log("updateFacility",res)
                            const res = response.data
                            loading.close()
                            this.addStatus = false
                            this.dialogFormVisible = false
                            this.$emit("updateTable")
                            if (res.code == 200) {

                                this.$message({type: "success", message: res.msg})
                            } else {
                                this.$message({type: "error", message: res.msg})
                            }
                        }).catch(err => {
                            loading.close()
                            console.log(res)
                            this.$message({type: "error", message: "添加设备服务器报错：" + err.toString()})
                            this.addStatus = false
                            this.dialogFormVisible = false
                        })
                    } else {
                        console.log('error submit!!')
                        return false
                    }
                });
            },
            addAction() {
                this.$refs.iotForm.validate((valid) => {
                    if (valid) {
                        this.addStatus = true
                        const params = this.$cloneDeep(this.form)
                        console.log("要添加的数据", params)
                        const loading = this.$load(this)
                        addFacility(params).then(response => {
                            console.log(res)
                            const res = response.data
                            loading.close()
                            this.addStatus = false
                            this.dialogFormVisible = false
                            this.$emit("updateTable")
                            if (res.code == 200) {

                                this.$message({type: "success", message: res.msg})
                            } else {
                                this.$message({type: "error", message: res.msg})
                            }
                        }).catch(err => {
                            loading.close()
                            console.log(res)
                            this.$message({type: "error", message: "添加设备服务器报错：" + err.toString()})
                            this.addStatus = false
                            this.dialogFormVisible = false
                        })
                    } else {
                        console.log('error submit!!')
                        return false
                    }
                });
            },
            async getLandInfo() {
                const response = await getLandProperties()
                const {msg} = response.data
                this.genJson = msg
            },
            initMap() {
                const _that = this
                // 鼠标圆点
                const raster = new TileLayer({
                    source: new OSM()
                });
                // 鼠标圆点
                this.source = new VectorSource();
                // 鼠标圆点
                const vector = new Vector({
                    source: this.source,
                    style: new Style({
                        fill: new Fill({
                            color: 'transparent',
                        }),
                        stroke: new Stroke({
                            color: '#ffcc33',
                            width: 2,
                        }),
                        image: new CircleStyle({
                            radius: 7,
                            fill: new Fill({
                                color: '#ffcc33',
                            }),
                        }),
                    }),
                });

                const baseStyle = new Style({
                    fill: new Fill({
                        color: "rgba(117,255,30,0.3)"
                    }),
                    stroke: new Stroke({
                        color: "#75ff1e",
                        width: 3
                    })
                })

                let zoom = 0;
                if (window.screen.availWidth == 3840) {
                    zoom = 18.6;
                } else if (window.screen.availWidth == 2560) {
                    zoom = 18;
                } else if (window.screen.availWidth == 1920) {
                    zoom = 17.6;
                } else if (window.screen.availWidth == 1600) {
                    zoom = 17.34;
                } else if (window.screen.availWidth == 1366) {
                    zoom = 17.1;
                } else {
                    zoom = 17.6;
                }
                this.map = new Map({
                    //地图容器ID
                    target: "mapDiv",
                    //引入地图
                    layers: [raster, this.image, vector],
                    view: new View({
                        //地图中心点
                        center: fromLonLat([121.8833790906, 44.7467653]),
                        // zoom: 17.6,
                        // minZoom:17.6 // 地图缩放最小级别
                        zoom: zoom,
                        minZoom: zoom, // 地图缩放最小级别
                        mouseWheelZoom: false
                        // extent: transformExtent(fromLonLat(extend), 'EPSG:4326', 'EPSG:3857')
                    })
                });
                const geoJsonObject = JSON.parse(this.genJson);
                const vectorSource = new VectorSource({
                    features: new GeoJSON().readFeatures(geoJsonObject, {
                        dataProjection: "EPSG:4326",
                        featureProjection: "EPSG:3857"
                    })
                });

                vectorSource.forEachFeature(feature => {
                    feature.setStyle(baseStyle);
                });

                const vectorLayer = new Vector({
                    source: vectorSource
                });

                this.map.addLayer(vectorLayer);

                this.addInteractions()

                this.map.on('singleclick', (e) => {
                    this.pointArray.push(e)
                    this.$confirm('此操作将设备位置的经度、纬度设定为选中地点, 是否继续?', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(() => {
                        this.form.locationEw = e.coordinate[0]
                        this.form.locationNs = e.coordinate[1]
                        this.innerVisible = false
                    }).catch(() => {
                        // 去除掉点
                        vector.getSource().getFeatures().forEach((feature) => {
                            vector.getSource().removeFeature(feature)
                        })
                    });

                })

                // 删除默认的双击事件
                const dblClickInteraction = this.map
                    .getInteractions()
                    .getArray()
                    .find(interaction => {
                        return interaction instanceof DoubleClickZoom;
                    });
                this.map.removeInteraction(dblClickInteraction);
                // 删除默认的拖拽事件
                const dragInteraction = this.map
                    .getInteractions()
                    .getArray()
                    .find(interaction => {
                        return interaction instanceof DragPan;
                    });
                this.map.removeInteraction(dragInteraction);
                //删除默认滑轮
                const zoomInteraction = this.map
                    .getInteractions()
                    .getArray()
                    .find(interaction => {
                        return interaction instanceof MouseWheelZoom;
                    });
                this.map.removeInteraction(zoomInteraction);
            },
            addInteractions() {
                this.draw = new Draw({
                    source: this.source,
                    type: "Point",
                });
                this.map.addInteraction(this.draw);
                this.snap = new Snap({source: this.source});
                this.map.addInteraction(this.snap);
            },
            open() {
                this.getLandInfo()
            },
            close() {
                this.imageUrl = ''
                this.form.id = undefined
                Object.assign(this.$data.form, this.$options.data().form)
                this.$refs.iotForm.resetFields()
                this.$refs.iotForm.clearValidate()
            },
            handleClickMap() {
                this.innerVisible = true
                this.$nextTick(() => {
                    this.initMap()
                })
            },
            requestBaseMap(){
                this.raster = new TileLayer({
                    source: new OSM(),
                });
                this.image = new Image({
                    source: new ImageWMS({
                        //不能设置为0，否则地图不展示。
                        ratio: 1,
                        url: "http://8.130.53.217:8080/geoserver/xam/wms",
                        params: {
                            FORMAT: "image/jpeg",
                            VERSION: "1.1.1",
                            STYLES: "",
                            LAYERS: "xam:1",
                            exceptions: "application/vnd.ogc.se_inimage"
                        }
                    })
                });
            },
            uploadSectionFile({file, onError, onSuccess}) {
                console.log("uploadSectionFile",file)
                const fileType = file.type,
                    fileName = file.name,
                    isImage = fileType.indexOf("image") != -1,
                    isLt500KB = file.size / 1024 < 500;
                // 这里常规检验，看项目需求而定
                if (!isImage) {
                    this.$message.error("只能上传图片格式png、jpg、gif!");
                    return;
                }
                if (!isLt500KB) {
                    this.$message.error("只能上传图片大小小于500KB");
                    return;
                }
                const formData = new FormData();
                formData.append("file", file)
                const loading = this.$load(this)
                upload(formData).then(res => {
                    if (res.data.code == 200) {
                        this.form.photoUrl = res.data.data.path
                        this.imageUrl = res.data.data.url + this.form.photoUrl
                    }
                    loading.close()
                }).catch(err => {
                    console.log(err)
                    loading.close()
                    this.$message({type: 'error', message: "上传异常:" + err})
                })
            }
        }
    };
</script>
<style>
  .ol-uncollapsible {
    display: none;
  }
</style>
<style scoped>

  .custom-dialog >>> .el-input.is-disabled .el-input__inner {
    background-color: #fff;
    color: #606266;
  }

  .custom-dialog >>> .el-textarea.is-disabled .el-textarea__inner {
    background-color: #fff;
    color: #606266;
  }

  .custom-dialog >>> .el-dialog {
    width: 900px !important;
    position: relative;
  }

  .custom-dialog >>> .el-dialog__header {
    background: #009865;
    padding: 10px 10px 10px;
  }

  .custom-dialog >>> .el-dialog__headerbtn {
    top: 9px !important;
    right: 10px !important;
  }

  .custom-dialog >>> .el-dialog__body {
    line-height: 0px !important;
  }
  .driver-uploader {
    border: 1px solid #606266;
  }

  .driver-uploader .el-upload {
    border: 1px dashed #009865;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }

  .driver-uploader .el-upload:hover {
    border-color: #009865;
  }

  .avatar-uploader-icon {
    font-size: 28px;
    color: #009865;
    width: 120px;
    height: 120px;
    line-height: 120px;
    text-align: center;
  }

  .avatar {
    width: 120px;
    height: 120px;
    display: block;
  }
</style>
